home *** CD-ROM | disk | FTP | other *** search
- How to crack "uncrackable" test4 by LordByte
-
- by Crook, 14 June 1997
- updated on 8 August 1997
-
-
- What is test4?
-
-
- Test4 is fourth in row of small challanges from LordByte. This one is
- 1251 bytes long and it was uncrackable for some time (I don't know when it was
- written). Quoting author of this test "the only purpose of it is to challenge
- superior Crackers. ONLY password can be accepted. NO PATCH can qualify!".
- The technique used in this test is called one-time pad. If every
- variation of this method is so easily cracked, you can forget about it.
-
- Target audience of this tutorial
-
-
- Everyone wishing to learn something. You MUST know assembly and basic
- math before trying to read this. Of course you can read without even trying to
- think how was it done, but it's just wasted time. The knowledge of C is also
- an advantage, because I'm going to show you program in C which does whole work
- for us.
-
-
- Brute force
-
-
- When there are passwords around there is also a brute force approach. But
- after short calculations I've started to think about some smarter method.
- There are 2^96 possible passwords. Assuming that you've written a
- program, which can check 1 million passwords per second, it means you have to
- wait 2^49 years, until it finishes.
- After I've cracked test4 I realized that there are 2^60 possible
- passwords. But even knowing this brute force is slow: statisticaly for every
- 2^36 wrong passwords, there is one good. Checking million passwords per second
- it would take about 18 hours. My method takes about 1 minute on 486DX/33... ;)
- [This paragraph was dedicated to ACP]
-
- Let's start
-
-
- The first thing you must do is to understand the test4.com. Run your
- favourite debugger (Turbo Debugger will be enough) and look deeply into the
- code, trying to understand what's doing inside of it. Without perfect
- understanding of method password is processed you won't be able to understand
- further parts of this tut. However, below is disassembly of vital parts of
- test4.com to help you with this task.
-
- mov dx, offset text1
- call show_text
- call hook_int
- mov dx, offset text2
- call show_text
- mov dx, offset buffer
- mov ax, 0A00h ; get password
- int 21h
-
- This is the start of TEST4. You're writing some messages on the screen,
- hooking time interrupt to blink the frame (patched by me, so there will be no
- such effect), and getting password into the buffer. As far, nothing
- complicated.
-
- start:
- mov ebx, 0
- get_4_bytes_out_of_password_into_eax:
- lea esi, [ebx+offset password]
- lea edi, table
- mov eax, [esi]
- cmp ah, 0Dh
- jz manipulate_with_password
- do_xor:
- xor [edi], eax
- rol eax, 2
- inc edi
- cmp dword ptr [edi+4], 0
- jnz do_xor
- inc ebx
- jmp short get_4_bytes_out_of_password_into_eax
-
- Let me tell you what's going there. In start you're zeroing ebx, which is
- index register from now on - it's char number in password. Next, load into esi
- address of char number ebx in password, and into edi address of the table,
- which will be xored by the values depending on password. Then you're getting 4
- bytes of the password into eax and checking if you're on the end of the
- password. If you are, then you must change password (of course by xoring it by
- some values).
- Code after do_xor label is the main part of this program. Four bytes in
- the table are xored by the eax. Then eax is rolled 2 bits to the left, index
- in the table (edi) is increased by one. You don't want to xor anything except
- the table, so there must be checking if you're out of table boundaries, which
- is done in the next line. If you've whole table xored, the ebx (index in the
- password) is increased by one, and the whole story begins once again.
-
- manipulate_with_password:
- lea esi, table
- mov eax, [esi]
- lea esi, password
- xor [esi], eax
- xor [esi+4], eax
- xor [esi+8], eax
- inc pass_count
- cmp pass_count, 3
- jnz not_3_pass
- mov xor_key, eax
- not_3_pass:
- cmp pass_count, 5
- jnz start
-
- This part is easy to understand: get first four bytes from the table into
- eax, then xor password with it. Next increase pass count. If it's third pass,
- you're storing eax for later use (to decrypt ciphered message). If it's fifth,
- you can go further.
-
- mov ebx, 0
- check:
- lea esi, [ebx+offset table]
- lea edi, [ebx+offset target_table]
- mov eax, [esi]
- xor [edi], eax
- jnz bad_password
- add ebx, 4
- cmp dword ptr [esi+4], 0
- jnz check
-
- This piece of code is also pretty obvious - the good password transforms
- original table into target_table (also stored in file). Checking if the
- password is good is reduced to check if both, table and target_table, are the
- same. Above snippet of code does just that - if the tables are different it
- means the password is bad. If they're the same - OK, user is a good cracker ;)
-
- mov si, good_password_message
- mov eax, xor_key
- xor_message:
- xor [si], al
- rol eax, 4
- inc si
- cmp byte ptr [si], 24h
- jnz xor_message
- mov dx, good_password_message
- call show_text
- jmp short end_program
-
- Here the text is decrypted. The algorithm is very simple, however you
- should study it, because it's important part of the crack.
- If you perfectly understand what is going on you can read furher - if you
- have any doubts then read this again and again until you understand. It is
- strongly recommended to know exactly how it works.
-
-
- Main idea of crack (or, should I say, croock ;)
-
-
- The target_table can be presented as a row of bits. Nothing exciting
- about this. But it can be also presented as value (0 or 1) and number of bits
- from the password it is xored. And that's exciting, because it's the main idea
- which allowed me to make C program to crack this program. Don't worry if you
- don't understand anything - I'll show you an example.
- Let's assume you've got target value: 0xe9, and the source value: 0x5f.
- You've got also a "magic box" which transforms source value into target value:
-
- source value (0x5f) --> [MAGIC BOX] --> target_value (0xe9)
-
- You also know that magic box uses just xor to transform values. You even
- know the schema of this xors, but we don't know the password. Let's say the
- password has 4 bits.
-
- 0 bit from source xored by 0, 1, 3 bits from password gives 0 bit from target
- 1 bit from source xored by 1, 2, 3 bits from password gives 1 bit from target
- 2 bit from source xored by 0 bit from password gives 2 bit from target
- 3 bit from source xored by 1, 2 bits from password gives 3 bit from target
- 4 bit from source xored by 3 bit from password gives 4 bit from target
- 5 bit from source xored by 2, 3 bits from password gives 5 bit from target
- 6 bit from source xored by 0, 3 bits from password gives 6 bit from target
- 7 bit from source xored by 1, 3 bits from password gives 7 bit from target
-
- This allows us to recover the password. How? By creating eight linear
- equations. Symbol 0s means bit 0 from source, 7t - seventh bit from target, 2p
- - second bit from password. Above 8 conditions can be written as:
-
- 0s xor 0p xor 1p xor 3p = 0t
- 1s xor 1p xor 2p xor 3p = 1t
- 2s xor 0p = 2t
- 3s xor 1p xor 2p = 3t
- 4s xor 3p = 4t
- 5s xor 2p xor 3p = 5t
- 6s xor 0p xor 3p = 6t
- 7s xor 1p xor 3p = 7t
-
- You know source and targets bits so you can change 0s, 1s and so on into
- values:
-
- (0x5f) (0xe9)
-
- 1 xor 0p, 1p, 3p = 1
- 1 xor 1p, 2p, 3p = 0
- 1 xor 0p = 0
- 1 xor 1p, 2p = 1
- 1 xor 3p = 0
- 0 xor 2p, 3p = 1
- 1 xor 0p, 3p = 1
- 0 xor 1p, 3p = 1
-
- By xoring both sides of equations by the values on the left side (this is
- basic math I've written earlier) you get:
-
- 0p xor 1p xor 3p = 0
- 1p xor 2p xor 3p = 1
- 0p = 1
- 1p xor 2p = 0
- 3p = 1
- 2p xor 3p = 1
- 0p xor 3p = 0
- 1p xor 3p = 1
-
- Solving this set of equations (using whichever method - e.g. using sheet
- of paper and a pencil ;) you get:
-
- 0p = 1
- 1p = 0
- 2p = 0
- 3p = 1, so the password is 1001.
-
- I think the main idea is clear now: you must build up a schema of xoring
- for every bit in the table, on then solve the equations. This is not so simple
- as in the above examples - the table is 122 bytes long, so it's 976 bits, and
- for each you must build up an equations. Then you must solve these equations
- using some smart method, because solving 976 equations on sheet of paper would
- take ages. Using some programming language (e.g. C) you are now able to write
- a program which will do crack for us.
-
-
- Hey, wait a minute
-
-
- Above explanations are true, but you're forgetting about one thing - in
- the third pass (if you don't remember - please study the code again) you're
- storing eax into memory, and then this value is used to decipher some crypted
- text. Who can guearantee us, that password which will transform target into
- target_table will also generate valid key for decrypting this text? That's why
- you must build 32 equations extra for this condition. Finally you've got 1008
- instead of 976 equations.
-
-
- Finding xor_key
-
-
- All right, but how can you find this key? The answer is simple - the
- decrypted text should end with three bytes 0xd, 0xa, 0x24 (if you don't know
- why, study some info about int21/ah=9 function). The layout of the test4.com
- in memory looks like this:
-
- 0100 code
- 02c4 buffer for password
- 02d3 "Enter password" text
- 02ea table
- 036a ciphered text
- 03b5 target_table
-
- target_table is zeroed after comparing function (check label) if table
- and target_table are the same, so the last three bytes of the ciphered text
- are stored in 03b2, 03b3 and 03b4 offsets. It's 0x9e, 0x40 and 0xfe. 0x9e
- should be xored to 0xa, 0x40 to 0xd and 0xfe to 0x24. That means 0x9e is xored
- by 0x94, 0x40 by 0x4d and 0xfe by 0xda.
-
- 0x9e xor 0x94 = 0xa
- 0x40 xor 0x4d = 0xd
- 0xfe xor 0xda = 0x24
-
- In eax you've got the key. I'm assuming every letter is a nibble (4
- bits):
-
- eax: abcdefgh
- al: gh
-
- So, first byte is xored by gh. Then eax is rolled 4 bits left:
-
- eax: bcdefgha
- al: ha
-
- Second byte is xored by ha, and so on. Look what happens when you're
- xoring ninth byte:
-
- 1: abcdefgh
- 2: bcdefgha
- 3: cdefghab
- 4: defghabc
- 5: efghabcd
- 6: fghabcde
- 7: ghabcdef
- 8: habcdefg
- 9: abcdefgh
-
- It means that key is same for bytes which are in the same column of the
- dump pane in TD.
-
- DS:036A D7 22 B4 C1 13 71 70 EC <-- This is dump panel from TD
- DS:0372 F8 2C AE .. .. .. .. ..
- ...
- DS:03B2 9E 40 FE .. .. .. .. ..
-
- Xoring D7,22,B4 by 94,4D,DA you get "Con". This should be beginning of
- the "Congratulations" string. Let's go further: xor D7,22,B4,C1,13,71,70,EC
- with "Congratu". You're getting 8 bytes: 94,4D,DA,A6,61,10,09,99. You've got
- whole information, but you must "pack" 8 bytes into 4. The lowest byte is
- 0x94. Then, after ROL EAX,4 you should get 0x4d in al. That means the highest
- nibble is 0xd. After next ROL al is 0xda, so the second highest nibble is 0xa.
- Going further, you can reconstruct the key, which is 0xda610994. Using this
- value, you can decrypt text:
- "Congratulations. You have done the what cannot be done .. Tell me how ?!"
- Wow! First success! You haven't done anything spectacular by now, but you
- will, don't worry ;)
-
-
- Program
-
-
- Whole source code for testcrk.c which is the main part of my work is included
- in ZIP file, UUENCODED at the end of this file. Below are the main parts of
- the code, commented as good as I can.
-
- ------------------------------------------------------------------------------
- #define KEYCHARS 16
- #define KEYBITS KEYCHARS * 8
- #define XORCHARS 122
- #define XORBITS XORCHARS * 8
- #define EQUATIONS XORBITS + 32
- #define KEYSIZE KEYBITS * (KEYBITS + 1)
- #define XORSIZE XORBITS * (KEYBITS + 1)
- ------------------------------------------------------------------------------
-
- KEYCHARS - number of chars in the buffer
- KEYBITS - number of bits in the buffer
- XORCHARS - size of table
- XORBITS - number of bits in the table
- EQUATIONS - number of equations to solve
- KEYSIZE - size of whole TabKey table
- XORSIZE - size of whole TabCipher table
-
- ------------------------------------------------------------------------------
- char huge TabKey[KEYBITS][KEYBITS+1]; // password
- char huge TabCipher[EQUATIONS][KEYBITS+1]; // table for XOR
- char AktKey[32][KEYBITS+1]; // current key
- char Temp[2][KEYBITS+1]; // temporary for ROL
- char TabPass[KEYBITS]; // password divided into bits
- char password[KEYCHARS];
- char TempEqu[12 * 8 + 1]; // temp for swap_equ
- unsigned char solved[EQUATIONS];
- ------------------------------------------------------------------------------
-
- TabKey - table where the key (whole 16-char buffer) will be stored, divided
- into bits. If the n-th bit is set to 1 (0 < n < KEYBITS), that means
- this bit is XORed by n-th from the buffer. If the KEYBITS bit is set
- it means it is XORed by 1.
- TabCipher - table where the table is stored, divided into bits. Format same as
- above.
- AktKey - key divided into bits (value stored in eax, used to XOR bytes from
- table). Format same as above.
- Temp - temporary table to perform ROL EAX,2 on AktKey
- TabPass - password divided into bits. If the n-th bit is set, it means the
- n-th bit in the password is 1. If not - the bit is 0. WARNING: I've
- implemented other bit numbering system: bit 0 is the most
- significant bit, and the (KEYBITS-1) is the least significant.
- password - password in bytes. Used by do_test() routine. Just for testing
- purposes. Left for historical reasons ;)
- TempEqu - temporary swap space for swap_equ functions, which swaps places of
- two equations
- solved - if the n-th element of this table is set, that means it was used to
- calculate some bit in password. More details on solve() functions
- comment
-
- ------------------------------------------------------------------------------
- FILE *org;
- char passsize;
- char size_pass[] = {11, 14, 14, 14};
- char passchars = 0, passbits = 0;
- char yesorno;
- ------------------------------------------------------------------------------
-
- org - file struct, used on file operations
- passsize - current password size, more details on create_table() function
- comment
- size_pass - table to get passsize from, more details on create_table()
- function comment
- passchars - number of letters in password. Set by user.
- passbits - number of bits in password. Set by user.
-
- ------------------------------------------------------------------------------
- void create_table()
- ------------------------------------------------------------------------------
-
- Function which is the alfa & omega here. Creates the XOR schema.
-
- ------------------------------------------------------------------------------
- int i, j;
- unsigned char mask, chr, byte[XORCHARS];
- long cipherpos;
- int pass, keychar, bits, xor_char;
- unsigned char buffer[KEYBITS + 1];
- ------------------------------------------------------------------------------
-
- i, j - counters, used in various for loops
- mask, chr, byte, cipherpos - used when loading ORG.DAT
- pass - pass index
- keychar - char index from the password processed
- bits - bit index when xoring table by eax
- xor_char - char index when xoring table by eax
- buffer - buffer used when reading from CIPHER.DAT
-
- ------------------------------------------------------------------------------
- if ((org = fopen("CIPHER.DAT", "rb")) != NULL)
- {
- fread(byte, 1, 1, org);
- if (byte[0] == passchars)
- {
- printf("reading from CIPHER.DAT...\n");
- for (i = 0; i < EQUATIONS; i++)
- {
- fread(buffer, KEYBITS+1, 1, org);
- // we cannot use _fmemcpy, coz it fails sometimes on huge tables
- for (j = 0; j <= KEYBITS; j++)
- TabCipher[i][j] = buffer[j];
- }
- fclose(org);
- return;
- }
- }
- ------------------------------------------------------------------------------
-
- Above piece of code loads the equations from CIPHER.DAT, instead of
- creating them from scratch. This file is created on the end of create_table().
- Speeds up the process of cracking after first time.
-
- ------------------------------------------------------------------------------
- memset(TabPass, 0, KEYBITS);
- _fmemset(TabKey, 0, KEYSIZE); // initiate TabKey
- for (i = 0; i < passbits; i++) // set passbits bits
- TabKey[i][i] = 1;
- TabKey[passchars*8][KEYBITS] = 0; // char after password is 0x0d
- ...
- TabKey[13*8][KEYBITS] = 0; // 13th char is 0x0a
- ...
- TabKey[14*8][KEYBITS] = 0; // on 14th pos we've got 0x0d
- ...
- TabKey[15*8][KEYBITS] = 0; // on 15th there's is 0x20
- ...
- passsize = passchars;
- ------------------------------------------------------------------------------
-
- Initialization code. Sets up bits like in the original test4.com:
-
- x|x|x|x|x|x|x|x|x|x|x|x|0xd|0xa|0x0d|0x20|
- this is the case when the password has 12 chars.
-
- x|x|x|x|x|x|x|x|x|x|0xd|0|0|0xa|0x0d|0x20|
- it looks like this, when the password has 10 chars.
-
- ------------------------------------------------------------------------------
- if ((org = fopen("ORG.DAT", "rb")) == NULL)
- {
- printf("ORG.DAT not found!\n");
- exit(255);
- }
-
- _fmemset(TabCipher, 0, XORSIZE); // initiate TabCipher
- cipherpos = 0;
- fread(byte, XORCHARS, 1, org);
- fclose(org);
- for (i = 0; i < XORCHARS; i++)
- for (mask = 0x80; mask != 0; mask >>= 1)
- {
- if ((byte[i] & mask) == mask) TabCipher[cipherpos][KEYBITS] = 1;
- cipherpos++;
- }
- ------------------------------------------------------------------------------
-
- Loads the ORG.DAT into memory and transforms it into bits. ORG.DAT is
- table stored in separate file.
-
- ------------------------------------------------------------------------------
- for (pass = 0; pass < 5; pass++)
- {
- for (keychar = 0; keychar < (passsize - 1); keychar++)
- {
- putch('.');
- memcpy(AktKey, TabKey[keychar*8+24], 8*(KEYBITS+1)); // get current key
- memcpy(AktKey[8], TabKey[keychar*8+16], 8*(KEYBITS+1)); // but reversed
- memcpy(AktKey[16], TabKey[keychar*8+8], 8*(KEYBITS+1));
- memcpy(AktKey[24], TabKey[keychar*8], 8*(KEYBITS+1));
- ------------------------------------------------------------------------------
-
- When you execute instruction
- MOV EAX,[ESI]
- and in [ESI] you've got
- ABCD
- where A, B, C, D are bytes, in EAX you get
- DCBA
- That's why you must copy to AktKey using this strange-looking code.
-
- ------------------------------------------------------------------------------
- for (xor_char = 0; xor_char <= (XORCHARS - 4); xor_char++)
- {
- for (bits = 24; bits < 32; bits++)
- do_xor(TabCipher[xor_char * 8 + bits - 24], AktKey[bits]);
- for (bits = 16; bits < 24; bits++)
- do_xor(TabCipher[xor_char * 8 + bits - 8], AktKey[bits]);
- for (bits = 8; bits < 16; bits++)
- do_xor(TabCipher[xor_char * 8 + bits + 8], AktKey[bits]);
- for (bits = 0; bits < 8; bits++)
- do_xor(TabCipher[xor_char * 8 + bits + 24], AktKey[bits]);
- memcpy(Temp, AktKey, 2 * (KEYBITS + 1));
- memmove(AktKey, AktKey[2], 30 * (KEYBITS + 1));
- memcpy(AktKey[30], Temp, 2 * (KEYBITS + 1));
- }
- ------------------------------------------------------------------------------
-
- Does right XORing. Because the XOR [ESI], EAX behaves like written in
- above comment we have to do it also in reverse byte order. The next 3
- instructions are equivalent to ROL EAX,2
-
- ------------------------------------------------------------------------------
- for (bits = 0; bits < 32; bits++)
- {
- do_xor(TabKey[bits], TabCipher[bits]);
- do_xor(TabKey[32 + bits], TabCipher[bits]);
- do_xor(TabKey[64 + bits], TabCipher[bits]);
- }
- ------------------------------------------------------------------------------
-
- After finished pass you must XOR password with the beginning of table.
-
- ------------------------------------------------------------------------------
- if (pass == 2) set_eax();
- if (passsize < 12) passsize = 14;
- ------------------------------------------------------------------------------
-
- When it's third pass (first pass has number 0 assigned) we must build
- that 32 additional equations (done in set_eax()).
- Remember when the process of XORing was stopped, and next pass was
- begining? When the AH was 0dh. So, when the 0dh put after password by
- int21h/ah=0a function is inside the 12-byte snip, it's being XORed by some
- values from table and there's no 0dh to stop. The nearest 0dh is on the 14th
- position, and that's why when we have less then 12 chars in password we must
- set passsize after first pass to 14.
-
-
- ------------------------------------------------------------------------------
- create_equations()
- ------------------------------------------------------------------------------
-
- This function converts data stored in TabCipher to equations (also stored
- in TabCipher). The target_table, used for creating right hand side of
- equations is store in XOR.DAT file, which is a dump from TEST4.COM
-
- ------------------------------------------------------------------------------
- solve()
- ------------------------------------------------------------------------------
-
- This function solves the equations created in TabCipher by
- create_equations() using Gauss-Jordan method. Let me show you the algorithm on
- example.
-
- Let's say we've got following set of equations
-
- a xor b xor d = 1
- c xor d = 0
- a xor c xor d = 1
- a xor c = 0
-
- It can be written also as
-
- 1*a xor 1*b xor 0*c xor 1*d = 1
- 0*a xor 0*b xor 1*c xor 1*d = 0
- 1*a xor 0*b xor 1*c xor 1*d = 1
- 1*a xor 0*b xor 1*c xor 0*d = 0
-
- Writing it in compact form:
-
- 1101 1
- 0011 0
- 1011 1
- 1010 0
-
- It's the format the equations are stored in TabCipher after create_equations()
- function was called. The Gauss-Jordan algorithm works like this:
-
- Let's eliminate 1 from the first column, leaving it just in first equation.
- How? By XORing all equations with 1 in the first column by first equation.
-
- 1101 1
- 0011 0
- 0110 0 <- 1101 xor 1011 = 0110, 1 xor 1 = 0
- 1010 0
-
- And XOR also fourth equation:
-
- 1101 1
- 0011 0
- 0110 0
- 0111 1 <- 1101 xor 1010 = 0111, 1 xor 0 = 1
-
- We haven't got 1 on second column and second row, so let's exchange second
- equation with third.
-
- 1101 1
- 0110 0 \
- 0011 0 /
- 0111 1
-
- Let's eliminate 1 from second column (except second row), firstly XOR first
- equation with second
-
- 1011 1 <- 1101 xor 0110 = 1011, 1 xor 0 = 1
- 0110 0
- 0011 0
- 0111 1
-
- Now XOR fourth equation by second
-
- 1011 1
- 0110 0
- 0011 0
- 0001 1 <- 0111 xor 0110 = 0001, 1 xor 0 = 1
-
- Do the same with third column.
-
- 1000 1
- 0101 0
- 0011 0
- 0001 1
-
- And, of course with last, fourth.
-
- 1000 1
- 0100 1
- 0010 1
- 0001 1
-
- The result is on the right hand side - first bit in first row, second in
- second, and so on. In my solve() I'm using a variation of this algorithm. I
- don't swap the equations, but I set appropriate bit in solved table. When bit
- is set in the solved table, that means this equation was used as a "base" to
- calculate one of the bits. More details in the source code - if you want know
- how it works - study it.
-
-
- After testcrk.c
-
-
- After running testcrk you'll get two new files - test.out and equ.dat.
- Reading the first one will bring first success - second and third bytes are,
- respectively, 'a' and 't'. EVERY valid, 12-char, password has to have "at"
- string on the second and third chars. I've written a showequ.c which converts
- equ.dat into equ.txt - human readable form. If you have thoroughly examined
- testcrk.c you'll also be able to understand showequ.c with ease. Run showequ
- and read equ.txt. The only two additional (to "at" string) conditions are:
-
- 1. password[1] = password[12] xor 6
- 2. password[4] = password[5] xor password[6] xor ... xor password[11] xor
- password[1] xor 57
-
- Just these three conditions should be met to generate a VALID password!
- (Look into genpass.c for details) BTW: The original password used by
- LordByte was "saturn404cpu" (try typing rn404cpu into genpass ;)
-
-
- Hey! Password generated by genpass.c doesn't work!
-
-
- The reason for this is very simple. Remember how test4 checks if it's the
- end of the password and it should begin next pass? It's checking for 0dh in ah
- register. When 0dh appears in some strange place (after xoring password with
- values from the table), the schema of xoring changes dramatically, so the
- equations produced by testcrk.c are useless, what makes password bad. Try
- entering "KurwaMac" (pozdrowienia dla wszystkich Polakow <- sorry, a bit of
- Polish here) into genpass, and then generated password into test4. Then run TD
- and look where this mysterious 0dh is appearing in the password.
-
-
-
- Counting password
-
-
- I don't know the exact number of passwords, that can be accepted by
- test4. However, using calculus of probability, I give you a good
- approximation. As shown in the previous paragraph, there is 8 significant
- (changeable) chars in password, 2 of chars are "checksums" of this eight, and
- 2 are constant ("at"). So, theoretically, there is 2^(8*8) passwords, which is
- 2^64. But you must remember about 0dh appearing in the password after XORing
- it. Let's assume (I don't know if it's right assumption. If you can give me a
- strict mathemathical proof, I would be pleased. Send all your tries to:
- croock@priv.onet.pl) that appearing 0dh on each of 12 positions has same
- likelihood. There are 4 passes where 0dh can appear, so it gives us 48
- possible positions. The likelihood of appearing 0dh in one position is like 1
- to 256. So the sumary likelihood of appearing at least one 0dh in password is
- 48/256, which is equal to 3/16. So, 3/16 of passwords has 0dh inside.
-
- 3 3 * 2^64
- -- * 2^64 = --------- = 3 * 2^60
- 16 2^4
-
- So, the probable number of passwords equals to:
-
- 2^64 - 3 * 2^60 = 2^60 * (2^4 - 3) = 13 * 2^60 ~= 2^64
-
- As stated above, this is only good approximation. Why? Maybe there are
- some passwords with 0dh, which are good ones. Maybe the the likelihood on each
- position is not the same. Maybe... However, the number of passwords is so big,
- it makes no difference ;)
-
- Final words
-
-
- I hope you understand this whole crap I wrote above, and I think you'll
- find it useful. If you have any comments, questions or some remarks please
- write to croock@priv.onet.pl.
- Message to all lamahows: don't steal my code, it is supposed to be a
- learning assistance, not the occasion to change CR00CK to your nick and tell
- the whole world how good you are.
- Greetz must go to LordByte for his test4 and Razzia for his (moral)
- support ;)
-
- Really final words
-
-
- Look out! TEST5 is going out. Search for another tutorial by me, now on
- cracking test5 :-)))
-
- mat=ByCr00ck
- 1at:14061997
-